/*
 * Lucas McDaniel
 * GSoC '11
 * HoneyViz
 * 
 * This class manages the caching of visualizations, searching criteria,
 * timing updates, and setting applet state.  This was added to reduce 
 * the load when redrawing each component by caching all the search 
 * criteria and the results that are generated based off of this.
 * 
 * Originally, it was the intent of this class to cache the (at the time) 
 * 3 types of visualizations and the hope that any additional component 
 * could use one of those 3.  However, this class has now ballooned to 
 * include many more cache types.  The next release will see a simplification 
 * of this static class using a CacheState class and restructuring it's 
 * affect on EventColorManager and HoneyData search critera.
 * 
 * Lots of the code may look redundant (hence the need for the CacheState 
 * class) as they serve very similar purposes.  Each component has its own 
 * 'local' cache of the applet state that was in effect the last time a query
 * was performed.  The current state is then verified by the cached version 
 * and if the relevant parts are the same, then the cached results are returned.
 * 
 * Each component can have as many or as few (including none) of these caches 
 * as deemed necessry.
 */

import java.util.ArrayList;

public class AppletState {
    
    public static final String url = "http://192.168.11.46/";
    
    private static boolean groupToCategory;
    private static int mapType;
    private static int botY, topY, sizeY;
    private static int botX, topX, sizeX;
    private static int sliderLocation;
    private static int timeInterval;
    public static final int FPS = 20;
    
    private static boolean makeHeat;
    
    private static boolean update;
    
    private static boolean makeDistinct;
    
    private static boolean cacheDistinct;
    
    private static boolean cacheHeat;
    
    private static int primaryViz;
    private static int secondaryViz;
    private static int primaryStat;
    private static int primarySearch;
    
    private static boolean cacheCategory;
    private static int cacheBotXB, cacheTopXB;
    private static int cacheBotYB, cacheTopYB;
    private static int cacheBotXL, cacheTopXL;
    private static int cacheBotYL, cacheTopYL;
    private static int cacheBotXS, cacheTopXS;
    private static int cacheBotYS, cacheTopYS;
    private static int cacheBotXR, cacheTopXR;
    private static int cacheBotYR, cacheTopYR;
    private static int cacheBotXF, cacheTopXF;
    private static int cacheBotYF, cacheTopYF;
    private static int cacheBotXT, cacheTopXT;
    private static int cacheBotYT, cacheTopYT;
    private static ArrayList cacheEvents;
    private static ArrayList currentResults;
    
    private static double[][] selectedLocations;
    
    //  Bar Cache Values
    
    private static ArrayList barList, lineList, sphereList, rectangleList, fullMapList, statsList;
    private static ArrayList barResult, lineResult, sphereResult, rectangleResult, fullMapResult, statsResult;
    
    private static boolean cacheCategoryBar, cacheDistinctBar, cacheHeatBar;
    private static boolean cacheCategoryLine, cacheDistinctLine, cacheHeatLine;
    private static boolean cacheCategorySphere, cacheDistinctSphere, cacheHeatSphere;
    private static boolean cacheCategoryRectangle, cacheDistinctRectangle, cacheHeatRectangle;
    private static boolean cacheCategoryFullMap, cacheDistinctFullMap, cacheHeatFullMap;
    private static boolean cacheCategoryStats, cacheDistinctStats, cacheHeatStats;
    
    private static int cacheTimeIntervalBar, cacheTimeIntervalLine, cacheTimeIntervalSphere, cacheTimeIntervalRectangle, cacheTimeIntervalFullMap, cacheTimeIntervalStats, cacheStatisticsState;
    private static double[][] cacheSelectedBar, cacheSelectedLine, cacheSelectedSphere, cacheSelectedRectangle, cacheSelectedFullMap, cacheSelectedStats;
    
    private static int mode;
    
    public static void firstLoad()
    {
        timeInterval = 0;
        sliderLocation = 0;
        groupToCategory = false;
        mapType = 1;
        resetSelected();
        update = true;
        makeHeat = false;
        makeDistinct = false;
        barResult = new ArrayList();
        lineResult = new ArrayList();
        sphereResult = new ArrayList();
        rectangleResult = new ArrayList();
        fullMapResult = new ArrayList();
        primaryViz = 0;
        secondaryViz = 0;
        primaryStat = 0;
        primarySearch = 0;
        selectedLocations = null;
        setStatisticStateBar();
        setStatisticStateLine();
        setStatisticStateSphere();
        setStatisticStateRectangle();
        setStatisticStateFullMap();
        setStatisticStateStats();
    }
    
    public static int getMode()
    {
        return mode;
    }
    
    public static void setMode(int val)
    {
        mode = val;
    }
    
    public static void setPrimaryViz(int val)
    {
        primaryViz = val;
        setMode(-1);
    }
    
    public static int getPrimaryViz()
    {
        return primaryViz;
    }
    
    public static void setSecondaryViz(int val)
    {
        secondaryViz = val;
        setMode(-1);
    }
    
    public static int getSecondaryViz()
    {
        return secondaryViz;
    }
    
    public static void setPrimaryStat(int val)
    {
        primaryStat = val;
        setMode(-1);
    }
    
    public static int getPrimaryStat()
    {
        return primaryStat;
    }
    
    public static void setPrimarySearch(int val)
    {
        primarySearch = val;
        setMode(-1);
    }
    
    public static int getPrimarySearch()
    {
        return primarySearch;
    }
    
    public static void setMapView()
    {
        setPrimaryViz(0);
        setSecondaryViz(0);
        setPrimaryStat(0);
        setPrimarySearch(0);
        setMode(0);
    }
    
    public static void setSphereView()
    {
        setPrimaryViz(1);
        setSecondaryViz(0);
        setPrimaryStat(1);
        setPrimarySearch(1);
        setMode(1);
    }
    
    public static void setHeat(boolean bool)
    {
        makeHeat = bool;
    }
    
    public static boolean isHeat()
    {
        return makeHeat;
    }
    
    public static void setDistinct(boolean bool)
    {
        makeDistinct = bool;
    }
    
    public static boolean isDistinct()
    {
        return makeDistinct;
    }
    
    public static void setGroupToCategory(boolean bool)
    {
        groupToCategory = bool;
    }
    
    public static boolean isGroupToCategory()
    {
        return groupToCategory;
    }
    
    public static void setTimeInterval(int val)
    {
        if (val > 3 || val < 0)
            timeInterval = 0;
        else
            timeInterval = val;
    }
    
    public static int getTimeInterval()
    {
        return timeInterval;
    }
    
    public static void setSliderLocation(int val)
    {
        if (val > 100 || val < 0)
            sliderLocation = 0;
        else
            sliderLocation = val;
    }
    
    public static int getSliderLocation()
    {
        return sliderLocation;
    }
    
    public static void setMapType(int val)
    {
        if (val > 2 || val < 1)
            mapType = 1;
        else
            mapType = val;
    }
    
    public static int getMapType()
    {
        return mapType;
    }
    
    public static void resetSelected()
    {
        topX = -1;
        topY = -1;
        botX = -1;
        botY = -1;
        resetSelectedLocations();
    }
    
    public static void setTopX(int x)
    {
        topX = x;
    }
    
    public static int getTopX()
    {
        return topX;
    }
    
    public static void setBotX(int x)
    {
        botX = x;
    }
    
    public static int getBotX()
    {
        return botX;
    }
    
    public static void setTopY(int y)
    {
        topY = y;
    }
    
    public static int getTopY()
    {
        return topY;
    }
    
    public static void setBotY(int y)
    {
        botY = y;
    }
    
    public static int getBotY()
    {
        return botY;
    }
    
    public static int getSizeX()
    {
        return sizeX;
    }
    
    public static void setSizeX(int val)
    {
        sizeX = val;
    }
    
    public static int getSizeY()
    {
        return sizeY;
    }
    
    public static void setSizeY(int val)
    {
        sizeY = val;
    }
    
    public static boolean isCacheBarLocation()
    {
        return botX == cacheBotXB && botY == cacheBotYB && topX == cacheTopXB && topY == cacheTopYB;
    }
    
    public static boolean isCacheLineLocation()
    {
        return botX == cacheBotXL && botY == cacheBotYL && topX == cacheTopXL && topY == cacheTopYL;
    }
    
    public static boolean isCacheSphereLocation()
    {
        return botX == cacheBotXS && botY == cacheBotYS && topX == cacheTopXS && topY == cacheTopYS;
    }
    
    public static boolean isCacheRectangleLocation()
    {
        return botX == cacheBotXR && botY == cacheBotYR && topX == cacheTopXR && topY == cacheTopYR;
    }
    
    public static boolean isCacheFullMapLocation()
    {
        return botX == cacheBotXF && botY == cacheBotYF && topX == cacheTopXF && topY == cacheTopYF;
    }
    
    public static boolean isCacheStatsLocation()
    {
        return botX == cacheBotXT && botY == cacheBotYT && topX == cacheTopXT && topY == cacheTopYT;
    }
    
    public static void cacheBarLocation()
    {
        cacheBotXB = botX;
        cacheTopXB = topX;
        cacheBotYB = botY;
        cacheTopYB = topY;
    }
    
    public static void cacheLineLocation()
    {
        cacheBotXL = botX;
        cacheTopXL = topX;
        cacheBotYL = botY;
        cacheTopYL = topY;
    }
    
    public static void cacheSphereLocation()
    {
        cacheBotXS = botX;
        cacheTopXS = topX;
        cacheBotYS = botY;
        cacheTopYS= topY;
    }
    
    public static void cacheRectangleLocation()
    {
        cacheBotXR = botX;
        cacheTopXR = topX;
        cacheBotYR = botY;
        cacheTopYR = topY;
    }
    
    public static void cacheFullMapLocation()
    {
        cacheBotXF = botX;
        cacheTopXF = topX;
        cacheBotYF = botY;
        cacheTopYF= topY;
    }
    
    public static void cacheStatsLocation()
    {
        cacheBotXT = botX;
        cacheTopXT = topX;
        cacheBotYT = botY;
        cacheTopYT= topY;
    }
    
    public static boolean sameStatisticState()
    {
        if (cacheCategory != groupToCategory)
            return false;
        if (cacheDistinct != makeDistinct)
            return false;
        if (cacheHeat != makeHeat)
            return false;
        return true;
    }
    
    public static void setStatisticState()
    {
        cacheCategory = groupToCategory;
        cacheDistinct = makeDistinct;
        cacheHeat = makeHeat;
    }
    
    public static boolean sameStatisticStateBar()
    {
        if (cacheCategoryBar != groupToCategory)
            return false;
        if (cacheDistinctBar != makeDistinct)
            return false;
        if (cacheHeatBar != makeHeat)
            return false;
        if (cacheTimeIntervalBar != timeInterval)
            return false;
        if (cacheSelectedBar != selectedLocations)
                return false;
        return true;
    }
    
    public static void setStatisticStateBar()
    {
        cacheCategoryBar = groupToCategory;
        cacheDistinctBar = makeDistinct;
        cacheHeatBar = makeHeat;
        cacheTimeIntervalBar = timeInterval;
        cacheSelectedBar = selectedLocations;
    }
    
    public static boolean sameStatisticStateLine()
    {
        if (cacheCategoryLine != groupToCategory)
            return false;
        if (cacheDistinctLine != makeDistinct)
            return false;
        if (cacheHeatLine != makeHeat)
            return false;
        if (cacheTimeIntervalLine != timeInterval)
            return false;
        if (cacheSelectedLine != selectedLocations)
                return false;
        return true;
    }
    
    public static void setStatisticStateLine()
    {
        cacheCategoryLine = groupToCategory;
        cacheDistinctLine = makeDistinct;
        cacheHeatLine = makeHeat;
        cacheTimeIntervalLine = timeInterval;
        cacheSelectedLine = selectedLocations;
    }
    
    public static boolean sameStatisticStateSphere()
    {
        if (cacheCategorySphere != groupToCategory)
            return false;
        if (cacheDistinctSphere != makeDistinct)
            return false;
        if (cacheHeatSphere != makeHeat)
            return false;
        if (cacheTimeIntervalSphere != timeInterval)
            return false;
        if (cacheSelectedSphere != selectedLocations)
                return false;
        return true;
    }
    
    public static void setStatisticStateSphere()
    {
        cacheCategorySphere = groupToCategory;
        cacheDistinctSphere = makeDistinct;
        cacheHeatSphere = makeHeat;
        cacheTimeIntervalSphere = timeInterval;
        cacheSelectedSphere = selectedLocations;
    }
    
    public static boolean sameStatisticStateRectangle()
    {
        if (cacheCategoryRectangle != groupToCategory)
            return false;
        if (cacheDistinctRectangle != makeDistinct)
            return false;
        if (cacheHeatRectangle != makeHeat)
            return false;
        if (cacheTimeIntervalRectangle != timeInterval)
            return false;
        if (cacheSelectedRectangle != selectedLocations)
                return false;
        return true;
    }
    
    public static void setStatisticStateRectangle()
    {
        cacheCategoryRectangle = groupToCategory;
        cacheDistinctRectangle = makeDistinct;
        cacheHeatRectangle = makeHeat;
        cacheTimeIntervalRectangle = timeInterval;
        cacheSelectedRectangle = selectedLocations;
    }
    
    public static boolean sameStatisticStateFullMap()
    {
        if (cacheCategoryFullMap != groupToCategory)
            return false;
        if (cacheDistinctFullMap != makeDistinct)
            return false;
        if (cacheHeatFullMap != makeHeat)
            return false;
        if (cacheTimeIntervalFullMap != timeInterval)
            return false;
        if (cacheSelectedFullMap != selectedLocations)
                return false;
        return true;
    }
    
    public static void setStatisticStateFullMap()
    {
        cacheCategoryFullMap = groupToCategory;
        cacheDistinctFullMap = makeDistinct;
        cacheHeatFullMap = makeHeat;
        cacheTimeIntervalFullMap = timeInterval;
        cacheSelectedFullMap = selectedLocations;
    }
    
    public static boolean sameStatisticStateStats()
    {
        if (cacheCategoryStats != groupToCategory)
            return false;
        if (cacheDistinctStats != makeDistinct)
            return false;
        if (cacheHeatStats != makeHeat)
            return false;
        if (cacheTimeIntervalStats != timeInterval)
            return false;
        if (cacheSelectedStats != selectedLocations)
            return false;
        if (cacheStatisticsState != getPrimaryStat())
            return false;
        return true;
    }
    
    public static void setStatisticStateStats()
    {
        cacheCategoryStats = groupToCategory;
        cacheDistinctStats = makeDistinct;
        cacheHeatStats = makeHeat;
        cacheTimeIntervalStats = timeInterval;
        cacheSelectedStats = selectedLocations;
        cacheStatisticsState = getPrimaryStat();
    }
    
    public static boolean update()
    {
        return update;
    }
    
    public static void setUpdate()
    {
        update = true;
    }
    
    public static void setUpdate(boolean b)
    {
        update = b;
    }
    
    
    
    public static void setSelectedLocations(double[][] loc)
    {
        selectedLocations = loc;
        setUpdate();
    }
    
    public static double[][] getSelectedLocations()
    {
        return selectedLocations;
    }
    
    //  Bar Cache Management
    
    public static void makeBarCache(ArrayList list, ArrayList result)
    {
        barList = list;
        barResult = result;
        cacheBarLocation();
        setStatisticStateBar();
    }
    
    public static boolean isInBarCache(ArrayList list)
    {
        if (update())
            return false;
        if (!sameStatisticStateBar())
            return false;
        if (!isCacheBarLocation())
            return false;
        if (list == null || barList == null)
            return false;
        if (list.size() != barList.size())
            return false;
        for (int inc=0; inc<list.size(); inc++)
            if (((String)list.get(inc)).compareTo((String)barList.get(inc))!=0)
                return false;
        return true;
    }
    
    public static ArrayList getBarCache()
    {
        return barResult;
    }
    
    public static void seedBarCache()
    {
        
    }
    
    //  Line Cache Management
    
    public static void makeLineCache(ArrayList list, ArrayList results)
    {
        lineList = list;
        lineResult = results;
        cacheLineLocation();
        setStatisticStateLine();
    }
    
    public static boolean isInLineCache(ArrayList list)
    {
        if (update())
            return false;
        if (!sameStatisticStateLine())
            return false;
        if (!isCacheLineLocation())
            return false;
        if (list == null || lineList == null)
            return false;
        if (list.size() != lineList.size())
            return false;
        for (int inc=0; inc<list.size(); inc++)
            if (((String)list.get(inc)).compareTo((String)lineList.get(inc))!=0)
                return false;
        return true;
    }
    
    public static ArrayList getLineCache()
    {
        return lineResult;
    }
    
    public static void seedLineCache()
    {
        
    }
    
    //  Sphere Cache Management
    
    public static void makeSphereCache(ArrayList list, ArrayList results)
    {
        sphereList = list;
        sphereResult = results;
        cacheSphereLocation();
        setStatisticStateSphere();
    }
    
    public static boolean isInSphereCache(ArrayList list)
    {
        if (update())
            return false;
        if (!sameStatisticStateSphere())
            return false;
        if (!isCacheSphereLocation())
            return false;
        if (list == null || sphereList == null)
            return false;
        if (list.size() != sphereList.size())
            return false;
        for (int inc=0; inc<list.size(); inc++)
            if (((String)list.get(inc)).compareTo((String)sphereList.get(inc))!=0)
                return false;
        return true;
    }
    
    public static ArrayList getSphereCache()
    {
        return sphereResult;
    }
    
    public static void seedSphereCache()
    {
        
    }
    
    //  Sphere Cache Management
    
    public static void makeRectangleCache(ArrayList list, ArrayList results)
    {
        rectangleList = list;
        rectangleResult = results;
        cacheRectangleLocation();
        setStatisticStateRectangle();
    }
    
    public static boolean isInRectangleCache(ArrayList list)
    {
        if (update())
            return false;
        if (!sameStatisticStateRectangle())
            return false;
        if (!isCacheRectangleLocation())
            return false;
        if (list == null || rectangleList == null)
            return false;
        if (list.size() != rectangleList.size())
            return false;
        for (int inc=0; inc<list.size(); inc++)
            if (((String)list.get(inc)).compareTo((String)rectangleList.get(inc))!=0)
                return false;
        return true;
    }
    
    public static ArrayList getRectangleCache()
    {
        return rectangleResult;
    }
    
    public static void seedRectangleCache()
    {
        
    }
    
    //  Full Map Cache Management
    
    public static void makeFullMapCache(ArrayList list, ArrayList results)
    {
        fullMapList = list;
        fullMapResult = results;
        cacheFullMapLocation();
        setStatisticStateFullMap();
    }
    
    public static boolean isInFullMapCache(ArrayList list)
    {
        if (update())
            return false;
        if (!sameStatisticStateFullMap())
            return false;
        if (!isCacheFullMapLocation())
            return false;
        if (list == null || fullMapList == null)
            return false;
        if (list.size() != fullMapList.size())
            return false;
        for (int inc=0; inc<list.size(); inc++)
            if (((String)list.get(inc)).compareTo((String)fullMapList.get(inc))!=0)
                return false;
        return true;
    }
    
    public static ArrayList getFullMapCache()
    {
        return fullMapResult;
    }
    
    public static void seedFullMapCache()
    {
        
    }
    
    //  Stats Management
    
    public static void makeStatsCache(ArrayList list, ArrayList results)
    {
        statsList = list;
        statsResult = results;
        cacheStatsLocation();
        setStatisticStateStats();
    }
    
    public static boolean isInStatsCache(ArrayList list)
    {
        if (update())
            return false;
        if (!sameStatisticStateStats())
            return false;
        if (!isCacheStatsLocation())
            return false;
        if (list == null || statsList == null)
            return false;
        if (list.size() != statsList.size())
            return false;
        for (int inc=0; inc<list.size(); inc++)
            if (((String)list.get(inc)).compareTo((String)statsList.get(inc))!=0)
                return false;
        return true;
    }
    
    public static ArrayList getStatsCache()
    {
        return statsResult;
    }
    
    public static void seedStatsCache()
    {
        
    }
    
    public static void resetSelectedLocations()
    {
        selectedLocations = null;
    }
}
